/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
package controller;

import java.util.ArrayList;

import model.Vocabulary;

import org.apache.log4j.Logger;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryConnection;

import controller.sesameDataConnector.AbstractDataConnector;

public class SearchController {

	public static Logger logger = Logger.getLogger(SearchController.class);
	
	public static String getQuery(String searchInput, String searchType, String searchField, String searchOption, String startPoint, String endPoint) {
		String query = "";
		
		//TODO: BUG in sesame: DISTINCT and LIMIT in 1 query does not work as distinct is assigned after limit and so less than limit will occur
		
		
		String predicate = "", extension1 = "", typeextensionfrom = "", typeextensionwhere = "";
		/* define the predicate with the option searchField
		0 ... any
		1 ... title
		2 ... description
		3 ... translation
		4 ... tag
		5 ... synonym 
		*/
		int sf = Integer.parseInt(searchField);
		switch(sf) {
			case 0: predicate = " p"; break;
			case 1: predicate = " <"+RDFS.LABEL.stringValue()+">"; break; 
			case 2: predicate = " <"+RDFS.COMMENT.stringValue()+">"; break; 
			case 3: predicate = " <"+Vocabulary.TRANSLATION.stringValue()+">"; break;
			case 4: predicate = " <"+Vocabulary.HASTAG.stringValue()+">"; break;
			case 5: predicate = " <"+Vocabulary.SYNONYM.stringValue()+">"; break;
			default: break;
		}
		predicate += " {L}";
		
		/* defines an extension for search LIKE, NOT
		0 ... contains
		1 ... equals	
		2 ... not
		*/
		int so = Integer.parseInt(searchOption);
		switch(so) {
			case 0: extension1 = " L LIKE \"*" + searchInput + "*\" IGNORE CASE"; break;
			case 1: extension1 = " L LIKE \"" + searchInput + "\" IGNORE CASE"; break;
			case 2: extension1 = " NOT L LIKE \"*" + searchInput + "*\" IGNORE CASE"; break;
			default: break;
		}
	
		/*define the searchType
		0 ... any
		1 ... om
		2 ... c
		3 ... att
		*/
		int st = Integer.parseInt(searchType);
		typeextensionfrom = " ; rdf:type {T}";
		switch(st) {
			case 0: 
				typeextensionwhere = " AND (T=<" + Vocabulary.CLASS +"> OR T=<" + Vocabulary.ONTOLOGYMODULE +"> OR T=<" + Vocabulary.OBJECTPROPERTY +"> OR T=<" + Vocabulary.DATATYPEPROPERTY +">)"; 
				break;
			case 1: 
				typeextensionwhere = " AND T=<" + Vocabulary.ONTOLOGYMODULE +">"; 
				break;
			case 2: 
				typeextensionwhere = " AND T=<" + Vocabulary.CLASS +">"; 
				break;
			case 3: 
				typeextensionwhere = " AND (T=<" + Vocabulary.OBJECTPROPERTY +"> OR T=<" + Vocabulary.DATATYPEPROPERTY +">)"; 
				break;
		}
		
		query = "SELECT DISTINCT s FROM {s}" + predicate + typeextensionfrom +  " WHERE" + extension1 + typeextensionwhere + " LIMIT 10 OFFSET " + startPoint;

		return query;
	}
	
	
	
	
	public static ArrayList<URI> getResult(String searchInput, String searchType, String searchField, String searchOption, String startPoint, String endPoint) {
		
		String query = getQuery(searchInput, searchType, searchField, searchOption, startPoint, endPoint);
		ArrayList<URI> res = new ArrayList<URI>();
		//System.out.println(query);
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {
				TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SERQL, query);
				TupleQueryResult result = tupleQuery.evaluate();
				try {			
					while (result.hasNext()) {
						res.add(new URIImpl(result.next().getValue("s").stringValue()));
					}
				} finally {
					result.close();
				}
			} finally {
				con.close();
			}
		}catch (Exception e) {
			logger.error(e);
		}
		return res;
	}
}
